#include <cstdlib>
#include "bankclient.h"
#include "common/dynobjectfactory.h"

using namespace std;
/*
 * 这个控制层和业务模型层进行连接的方式采用一个map来实现，具体来说通过在某个具体项目中约定的协议进行数据交互，
 * 也就是定义key值对应的数据，这样达到数据的交互。就本次开发来说，每一个窗口都有通信协议，然后业务模型层出错会
 * 使用一个key为"errorMsg"的键值对将错误情况跑出来，可以进行读取查看。
 */
//执行访问操作
bool BankClient::execDataAccess()
{
    if(NULL == bda_) {
        errorMsg_ = "bda_ is NULL";
        return false;
    }
    //判断是否连接上，没有连接上就重试
    if(QAbstractSocket::UnconnectedState == cliPipe_->state()) {
        errorMsg_ = "host can't connect!please wait a moment now retry.";
        cliPipe_->connectToHost(host_,port_,QIODevice::ReadWrite);
        return false;
    }
    //数据进行请求发送
    if(!bda_->requestData(cliPipe_,rDataMap_)) {
        errorMsg_ = "requestData failure";
        return false;
    }
    //对数据进行响应
    if(!bda_->responseData(cliPipe_,rDataMap_)) {
        errorMsg_ = "responseData failure";
        return false;
    }
    return true;
}

//设置本次请求响应类型
bool BankClient::setReqResType(const char * type)
{
    //用来装载已经创建的业务数据连接
    map<QString,QSharedPointer<BankDataAccess> >::const_iterator it;
    it = bdaMap_.find(type);
    if(it != bdaMap_.end()) {
        bda_ = it->second;
    } else {
        //根据对象类型动态创建对象
        QSharedPointer<BankDataAccess> bda(static_cast<BankDataAccess *>(DynObjectFactory::createObject(type)));
        bda_ = bda;
        if(bda_.isNull()) {
            errorMsg_ = "Can't get object";
            return false;
        }
        bdaMap_.insert(make_pair(type,bda_));
    }
    return true;
}

//设置数据
void BankClient::setRawData(const char *key,const char *val)
{
    map<QString,QString>::const_iterator it;
    it = rDataMap_.find(key);
    if(it != rDataMap_.end()) {
        rDataMap_.erase(key);
    }
    rDataMap_.insert(make_pair(key,val));
}

//获取数据
const char *BankClient::getResRawData(const char *key) const
{
    map<QString,QString>::const_iterator it;
    it = rDataMap_.find(key);
    if(it != rDataMap_.end()) {
        memset(buf_,0,256);
        memcpy(buf_,(const char *)(it->second.toLocal8Bit()),it->second.length());
        return (const char *)buf_;
    }
    return "Not Found!";
}

//获取失败的原因数据
const char *BankClient::getErrorMsg(void) const
{
    static QString errorMsgString;
    map<QString,QString>::const_iterator it;
    it = rDataMap_.find("errorMsg");
    if(it != rDataMap_.end()) {
        errorMsgString.clear();
        errorMsgString = errorMsg_;
        errorMsgString += " : ";
        errorMsgString += it->second;
        memset(buf_,0,256);
        memcpy(buf_,(const char *)(errorMsgString.toLocal8Bit()),errorMsgString.length());
        return (const char *)buf_;
    } else {
        return errorMsg_;
    }
}

void BankClient::clear(void)
{
    bda_->resetDataAccess();
    rDataMap_.clear();
    errorMsg_ = "No Error";
}
